package mongodb

import (
	"context"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo/options"
	"go.uber.org/zap"
	"golang-sgg-daijia/internal/model"
)

type OrderServiceLocationDao interface {
	InsertMany(ctx context.Context, list []interface{}) (bool, error)
	GetNewestByOrderID(ctx context.Context, OrderID int64) (*model.OrderServiceLocation, error)
	FindByOrderIdOrderByCreateTimeAsc(ctx context.Context, orderId int64) ([]*model.OrderServiceLocation, error)
}

type orderServiceLocationDao struct {
    *MongoClient
}

func NewOrderServiceLocationDao(
	r *MongoClient,
) OrderServiceLocationDao {
    return &orderServiceLocationDao{
        r,
    }
}

func (r *orderServiceLocationDao) GetNewestByOrderID(ctx context.Context, OrderID int64) (*model.OrderServiceLocation, error) {
    orderServiceLocation := &model.OrderServiceLocation{}
	findOptions := options.FindOne().SetSort(bson.D{{"createtime", -1}})
	// 存到mongo的实体字段全变成小写了，推测是因为mongo默认设置不支持驼峰
	err := r.DB().Collection(orderServiceLocation.CollectionName()).
		FindOne(ctx, bson.D{{"orderid", OrderID}}, findOptions).
		Decode(orderServiceLocation)
    if err != nil {
        return nil, err
    }
    return orderServiceLocation, nil
}

func (r *orderServiceLocationDao) InsertMany(ctx context.Context, list []interface{}) (bool, error) {
	dbname := model.OrderServiceLocation{}.CollectionName()
	_, err := r.DB().Collection(dbname).InsertMany(ctx, list)
	if err != nil {
		r.logger.WithContext(ctx).Error("orderServiceLocationDao|InsertMany(", zap.Any("data", map[string]interface{}{
			"orderServiceLocationList": list,
		}), zap.Error(err))
		return false, err
	}

	return true, nil
}

func (r *orderServiceLocationDao) FindByOrderIdOrderByCreateTimeAsc(ctx context.Context, orderId int64) ([]*model.OrderServiceLocation, error) {
	var orderServiceLocationList []*model.OrderServiceLocation
	findOptions := options.Find()
	findOptions.SetSort(bson.D{{"createTime", -1}})

	cursor, err := r.DB().Collection(model.OrderServiceLocation{}.CollectionName()).
		Find(ctx, bson.M{"order_id": orderId}, findOptions)
	if err != nil {
		r.logger.WithContext(ctx).Error("orderServiceLocationDao|FindAll|Collection", zap.Any("data", map[string]interface{}{
			"orderId": orderId,
		}), zap.Error(err))
		return nil, err
	}
	err = cursor.All(ctx, &orderServiceLocationList)
	for cursor.Next(ctx) {
		var orderServiceLocation model.OrderServiceLocation
		if err := cursor.Decode(&orderServiceLocation); err != nil {
			r.logger.WithContext(ctx).Error("orderServiceLocationDao|FindAll|Decode", zap.Any("data", map[string]interface{}{
				"orderId": orderId,
			}), zap.Error(err))
			return nil, err
		}
		orderServiceLocationList = append(orderServiceLocationList, &orderServiceLocation)
	}
	return orderServiceLocationList, nil
}

